<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
 
    <!-- 防抖 -->
    <script>
        // 防抖：在间隔时间内多次触发事件，以最后一次为准
        // 思路：1.声明一个变量来存储定时器的id
        //2.每一次触发事件的时候，先不触发，开启定时器，间隔事件之后再触发
        //3.如果在间隔时间内，用户触发了其他事件，则结束上一次定时器，以最后一次为准


            // let timerId = null;
        //     console.log("id外面",timerId);

        // 这里的onresize其实跟我的timerId没有关系，我尺寸一改变我就触发这个监听事件，然后我的null就走进来了，
        // 然后null的时候我的清除定时器就走不进来，然后我就把setTimeout赋值给了timerId,然后我移动一次肯定会
        // 触发很多次，然后我就又走进来了，然后我就清除它们，然后到了最后一次，我就执行了setTimeout


        // 这里是异步事件，我异步事件要触发了才执行，同步事件是页面一渲染就执行，
        // 为什么我的外面的timerId一直都是null,就像我var a = 2; console.log(a);肯定是2啊 a =10;
        //     window.onresize = function(){
        //     // 其实这个null是没有走进setTimeout的，
        //     // 这里能够打印timerId为null是因为内部可以访问外部，但是外部不能访问内部
        //         // console.log("onresize下面一点点",timerId)
        //         timerId && clearTimeout(timerId);

        //         console.log("计算器下面",timerId)//1---null;

        //         timerId = setTimeout(() => {
        //            console.log("尺寸变化")
        //            console.log("定时器里面",timerId);
        //        }, 2000);
        //    }



        //    console.log("345678",timerId)


        // // var time = null;
        // window.onresize = function(){
        //     console.log("asdfgthj");
        //     time = setTimeout(() => {
        //         console.log(3456789)
        //     }, 2000);
        // }



        // 事件触发就会产生一个事件对象
        function debounce(fn, delay) {
            let timer = null
            return function (a) {
                // 设置了定时器就清空这个定时器，没有就去设置定时器
                timer && clearTimeout(timer)
                // 获取debounce执行作用域的this
                // 这个this指向debounce(fn, delay)，然后_this这个就是指向debounce
                let _this = this;
                // 获取参数
                // 这个arguments是一个伪数组，它可以拿到function里面传过来的值，
                // 所有的都可以拿到,两个也可以,是argument的特性
                let args = arguments
                console.log("a",a);//这里的a是访问的let a = 3里面的，因为我监听事件是在它的下面的
                console.log(args)

                timer = setTimeout(function () {
                    // args是 
                    fn.apply(_this, args)
                    console.log("尺寸变化");
                }, delay)
            }
        }



        let a = 3;

        //  先运行再传值,就是我先运行debounce(fn, delay),
        // 然后在运行的过程中我返回了一个函数,然后我再把值传进去
        window.addEventListener("resize",debounce(function(a){
            // 这里我的a是一个事件对象，然后我的代码是先运行再传参数，
            // 运行了就返回了一个函数return function () {}，然后我就把参数a传了进去
            // 然后我的args就接收了这个事件对象，然后我就把这个参数传给了fn,然后我这里就可以打印a,事件对象
            console.log(a);//会先访问内部的，不是3
            console.log("111");
        }),2000)

        //触发条件   触发函数

        // 这是我的监听事件，然后就是应该第二个值是function(){}
        // window.addEventListener("click",function() {

        // })


        // 为什么我要返回一个function，是因为我监听事件第二个值就是要返回一个function
        // function debounce(fn,delay){
        //     let timer = null;
        //     return function(){
        //         timer&&clearTimeout(timer);
        //         let that = this;
        //         let args = arguments;
        //         timer = setTimeout(() => {
        //     // 这里写fn是因为我要执行是就是fn
        //             fn.apply(that,args);
                  
        //             console.log("尺寸变化")
        //         }, delay);
        //     }
        // }

        // let a = 10
        // window.addEventListener("resize",debounce(function(a){
        //     console.log("34567");
        // },2000));









        // 节流
        // 节流：间隔时间内函数只被触发一次；解决高频事件触发的问题，降低触发的频率
        // 高频事件，触发频率最高的事件 onmousemove,onscoll

    
        // let timerId = null;
        // let flag = true;
        // window.onresize = function () {
        //     if (!flag) return;
        //     flag = false;
        //     timerId && clearInterval(timerId);
        //     timerId = setTimeout(function () {
        //         flag = true;
        //         console.log("尺寸变化");
        //     }, 500);
        // }




        // let timer=null;
        //节流阀
        //  允许执行
        // 这个flag就是我的一个标记，刚开始我的标记是flase,然后我的目的的减少触发的频率
        // 所以我就让为true的人不能进去，这个时候就只有我false能够进去，然后我以进去我就
        // 把门锁上，就不让另外的flase进来，然后我就进了定时器，然后我把我该做的事情做完了，
        // 2秒之后，这个时候我就把flag再该为false,再把门打开
        // let flag = false;

        // // 这里我第一次进来，我是false,然后我走不进if,然后我就让他为true,我第一次timer不存在
        // // 然后我的定时器就会给timer,然后我再两秒之内又触发了一次，这个时候我的flag为true,然后
        // // 我的就进入了if语句，然后我就跳出去了，但是这个时候我的定时器刚好走了两秒，然后我就执行了一次
        // // 这个时候我的flag就变成了false,然后我就又移动尺寸，然后我的if又进不来了，以此类推
        // window.onresize=function(){
        //     if(flag) return;
        //     flag = true;
        //     timer && clearTimeout(timer);
        //     // setTimeout是一创建就给了timer的
        //     timer = setTimeout(() => {
        //         console.log("123456");
        //         flag = false;
        //     }, 2000);
        // }





        // 这里是这样的，就是我执行了，返回了一个函数，然后我移动尺寸，我开始运行
        // 这个时候我为null,其实这个if语句的timer只是他能够内部访问外部，if进不来
        // 然后我就把定时器给了timer,然后我在2秒内触发了，然后我的timer现在有值，
        // 然后我就可以进入if语句，然后我就退出程序，然后这个时候我的上一个定时器
        // 执行完了，然后我的timer又为空，然后我就又进入程序，以此类推
        // function throttle(fn, delay) {
        //     let timer = null
        //     return function () {
        //         // 如果已经有定时器了，那么就退出
        //         if (timer) return
        //         // 获取debounce执行作用域的this
        //         let _this = this
        //         // 获取参数
        //         let args = arguments

        //         timer = setTimeout(function () {
        //             // 改变执行函数内部的this指向debounce执行作用域的this，并把参数传给执行函数
        //             fn.apply(_this, args)
        //             // 在delay后执行完fn之后清空timer，此时timer为假，throttle触发可以进入计时器
        //             timer = null
        //         }, delay)
        //     }
        // }

        // window.addEventListener("resize",throttle(function(){
        //     console.log(456789);
        // },2000))
    </script>
</body>

</html>